home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / cl182.zip / CL.HPT < prev   
Text File  |  1993-05-15  |  14KB  |  546 lines

  1. /*
  2.     cl.hpt -- Container Lite v 1.82 template
  3.     (C) Copyright 1993  John Webster Small
  4.     All rights reserved
  5. */
  6.  
  7.  
  8. #ifndef cl_hpt
  9. #define cl_hpt
  10.  
  11. #ifndef cl_hpp
  12. #include "cl.hpp"
  13. #endif
  14.  
  15. #include <string.h>
  16.  
  17.  
  18. /*  ITEM descriptors  */
  19.  
  20. // If your compiler's template facility doesn't
  21. // support nested function templates you must define
  22. // FNC_TEMPLATES_NO_NEST here or always invoke either
  23. // ITEM_BINARY_CMP() or ITEM_NO_REL_OPS(), or define
  24. // your own int CL_Dcmp() compare function before
  25. // container template instantiation.  "Form
  26. // templates" are actually more powerful in this
  27. // respect than C++ templates.
  28. // #define FNC_TEMPLATES_NO_NEST
  29.  
  30. #if defined(FNC_TEMPLATES_NO_NEST)
  31.  
  32. template <class ITEM>
  33. inline CLcmP(CL_DcmP(CLcmP(cmP,ITEM)),void)  \
  34. { return CLcmPcast(cmP,void); }
  35.  
  36. #else
  37.  
  38. template <class ITEM>
  39. int CL_Dcmp(const ITEM * D1, const ITEM * D2)
  40. { return ((*D1 == *D2)? 0 : ((*D1 > *D2)? 1 : -1)); }
  41.  
  42. // Must be invoked only one time, before container
  43. // template instantiation!
  44. #define ITEM_BINARY_CMP(ITEM)  \
  45. int CL_Dcmp(const ITEM * D1, const ITEM * D2) \
  46. { return memcmp(D1,D2,sizeof(ITEM)); }
  47.  
  48. template <class ITEM>
  49. inline CLcmP(CL_DcmP(CLcmP(cmP,ITEM)),void)
  50. { CLcmP(defaultCmP,ITEM) = CL_Dcmp;
  51.  return CLcmPcast((cmP? cmP : defaultCmP),void); }
  52.  
  53. #define ITEM_NO_REL_OPS(ITEM)  \
  54. inline CLcmP(CL_DcmP(CLcmP(cmP,ITEM)),void)  \
  55. { return CLcmPcast(cmP,void); }
  56.  
  57. #endif
  58.  
  59.  
  60. template <class ITEM>
  61.     inline void * CL_Dassign(ITEM * D,
  62.         const ITEM * S, unsigned)
  63.     { *D = *S; return (void *) D; }
  64. #define ITEM_TEST_ASSIGN(ITEM)  \
  65.     inline void * CL_Dassign(ITEM * D,  \
  66.         const ITEM * S, unsigned)  \
  67.     { return (void *) ((*D = *S)? D : 0); }
  68. #define ITEM_NO_ASSIGN(ITEM)  \
  69.     inline void * CL_Dassign(ITEM *,  \
  70.         const ITEM *, unsigned)  \
  71.     { return (void *) 0; }
  72.  
  73.  
  74. inline void * CL_Dnew(const char * D)
  75. { return strdup(D); }
  76. template <class ITEM>
  77.     inline void * CL_Dnew(const ITEM * D)
  78.     { return (void *) new ITEM(*D); }
  79. #define ITEM_CLONE(ITEM)  \
  80.     inline void * CL_Dnew(const ITEM * D)  \
  81.     { return (void *) D->clone(); }
  82. #define ITEM_NO_COPYINIT(ITEM)  \
  83.     inline void * CL_Dnew(const ITEM *)  \
  84.     { return (void *) 0; }
  85.  
  86. template <class ITEM>
  87.     inline void CL_Ddelete(ITEM * D)
  88.     { delete D; }
  89. #define ITEM_STRM_MUT_DELETE(ITEM)  \
  90.     inline void CL_Ddelete(ITEM * D)  \
  91.     { if (!D->RefCount()) delete D; }
  92. #define ITEM_NO_DELETE(ITEM)  \
  93.     inline void CL_Ddelete(ITEM *)  \
  94.     { return; }
  95.  
  96. template <class ITEM>
  97.     inline int CL_Dattach(ITEM *, const void *)
  98.     { return 1; }
  99. #define ITEM_LINK(ITEM) inline int CL_Dattach  \
  100.     (ITEM * D, const void * B)            \
  101.     { return D->link(B); }
  102.  
  103. template <class ITEM>
  104.     inline void CL_Ddetach(ITEM *, const void *)
  105.     {}
  106. #define ITEM_UNLINK(ITEM) inline void CL_Ddetach \
  107.     (ITEM * D, const void * B)                \
  108.     { D->unlink(B); }
  109.  
  110. inline ostream& operator<<(ostream& os, char ** D)
  111. {
  112.     int len = (*D? strlen(*D) : 0);
  113.     if ((os << len << endm))
  114.         if (len)
  115.             os.write(*D,len);
  116.     return os;
  117. }
  118. template <class ITEM>
  119.     inline ostream& operator<<(ostream& os,
  120.         ITEM ** D)
  121.     { return os << **D << endm; }
  122. #define ITEM_STRM_INSERT(ITEM,ITEM_STRM_BASE)    \
  123.     inline ostream& operator<<(ostream& os,  \
  124.         ITEM ** D)                       \
  125.     { return os << *(ITEM_STRM_BASE *)*D; }
  126. #define ITEM_BINARY_STRM_INSERT(ITEM)             \
  127.     inline ostream& operator<<(ostream& os,  \
  128.         ITEM ** D)                       \
  129.     { return os.write((char *)*D,sizeof(ITEM)); }
  130. #define ITEM_NO_STRM_INSERT(ITEM)                \
  131.     inline ostream& operator<<(ostream& os,  \
  132.         ITEM **) { return os; }
  133.  
  134. inline istream& operator>>(istream& is, char ** D)
  135. {
  136.     int len;
  137.     if (*D)  {
  138.         delete *D;
  139.         *D = (char *)0;
  140.     }
  141.     if ((is >> len >> nextm))
  142.         if (len)
  143.           if ((*D = new char[len+1])
  144.             != (char *)0)  {
  145.             is.read(*D,len);
  146.             (*D)[len] = '\0';
  147.           }
  148.           else
  149.             is.ignore(len);
  150.     return is;
  151. }
  152. template <class ITEM>
  153.     inline istream& operator>>(istream& is,
  154.         ITEM ** D)
  155.     {
  156.         if (*D) delete *D;
  157.         if ((*D = new ITEM) != (ITEM *)0)
  158.             is >> **D >> nextm;
  159.         return is;
  160.     }
  161. #define ITEM_STRM_EXTRACT(ITEM,ITEM_STRM_BASE)   \
  162.     inline istream& operator>>(istream& is,  \
  163.         ITEM ** D)                       \
  164.     {                                        \
  165.         ITEM_STRM_BASE * S;              \
  166.         is >> S;                         \
  167.         if (*D) delete *D;               \
  168.         *D = (ITEM *) S;                 \
  169.         return is;                       \
  170.     }
  171. #define ITEM_BINARY_STRM_EXTRACT(ITEM)           \
  172.         inline istream& operator>>(istream& is,  \
  173.         ITEM ** D)                       \
  174.     {                                        \
  175.      if (*D) delete *D;                      \
  176.      if ((*D = new ITEM) != (ITEM *)0)       \
  177.       return is.read((char *)*D,sizeof(ITEM));\
  178.      return is;                              \
  179.     }
  180.  
  181. #define ITEM_NO_STRM_EXTRACT(ITEM)               \
  182.     inline istream& operator>>(istream& is,  \
  183.         ITEM **) { return is; }
  184.  
  185. #define ITEM_BINARY_STRM(ITEM)           \
  186.     ITEM_BINARY_STRM_INSERT(ITEM)    \
  187.     ITEM_BINARY_STRM_EXTRACT(ITEM)
  188.  
  189. #define ITEM_BINARY_CMP_STRM(ITEM)       \
  190.     ITEM_BINARY_CMP(ITEM)            \
  191.     ITEM_BINARY_STRM(ITEM)
  192.  
  193. #define ITEM_NO_STRM_OPS(ITEM)        \
  194.     ITEM_NO_STRM_INSERT(ITEM)    \
  195.     ITEM_NO_STRM_EXTRACT(ITEM)
  196.  
  197. #define ITEM_NO_REL_STRM_OPS(ITEM)    \
  198.     ITEM_NO_REL_OPS(ITEM)        \
  199.     ITEM_NO_STRM_INSERT(ITEM)    \
  200.     ITEM_NO_STRM_EXTRACT(ITEM)
  201.  
  202. #define ITEM_DELETE_ONLY(ITEM)        \
  203.     ITEM_NO_REL_OPS(ITEM)        \
  204.     ITEM_NO_ASSIGN(ITEM)        \
  205.     ITEM_NO_COPYINIT(ITEM)        \
  206.     ITEM_NO_STRM_INSERT(ITEM)    \
  207.     ITEM_NO_STRM_EXTRACT(ITEM)
  208.  
  209. #define ITEM_BIND_ONLY(ITEM)     \
  210.     ITEM_DELETE_ONLY(ITEM)   \
  211.     ITEM_NO_DELETE(ITEM)
  212.  
  213. #define ITEM_STRMABLE(ITEM,ITEM_STRM_BASE)    \
  214.     ITEM_TEST_ASSIGN(ITEM)            \
  215.     ITEM_CLONE(ITEM)            \
  216.     ITEM_STRM_MUT_DELETE(ITEM)        \
  217.     ITEM_LINK(ITEM)                \
  218.     ITEM_UNLINK(ITEM)            \
  219.     ITEM_STRM_INSERT(ITEM,ITEM_STRM_BASE)    \
  220.     ITEM_STRM_EXTRACT(ITEM,ITEM_STRM_BASE)
  221.  
  222. #define ITEM_str                \
  223.     int CL_Dcmp                \
  224.       (const char * D1, const char * D2)    \
  225.     { return strcmp(D1,D2); }        \
  226.     ITEM_NO_ASSIGN(char)
  227. #define CL_str CL<char>
  228.  
  229.  
  230. template <class ITEM>
  231.  
  232. class CL : cl {
  233.  
  234.  
  235. protected:
  236.  
  237.     CL  (defaultConstructor)
  238.             : cl(defaultConstruct) {}
  239.     void     assign(const CL<ITEM>& b)
  240.             { cl::assign(b); }
  241.     cl::     destruct;
  242.     virtual  voidCmP DcmP(voidCmP cmP)
  243.             { return CL_DcmP
  244.             (CLcmPcast(cmP,ITEM)); }
  245.     virtual  void * Dassign(void * D,
  246.             const void * S)
  247.             { return CL_Dassign
  248.             ((ITEM *)D,(const ITEM *)S,
  249.             flags); }
  250.     virtual  void * Dnew(const void * D)
  251.             { return  CL_Dnew
  252.             ((const ITEM *)D); }
  253.     virtual  void   Ddelete(void * D)
  254.             { CL_Ddelete((ITEM *)D); }
  255.     virtual  int    Dattach(void * D)
  256.             { return CL_Dattach((ITEM *)D,
  257.             (const void *) this); }
  258.     virtual  void   Ddetach(void * D)
  259.             { CL_Ddetach((ITEM *)D,
  260.             (const void *) this); }
  261.     virtual     int    Dput(ostream& os, void * D)
  262.             { return ((os << (ITEM **) &D)?
  263.             1 : 0); }
  264.     virtual     void * Dget(istream& is)
  265.             { ITEM * D = 0; is >> &D;
  266.             return (void *) D; }
  267.     virtual  int    put(ostream& os)
  268.             { return cl::put(os); }
  269.     virtual  int    get(istream& is)
  270.             { return cl::get(is); }
  271.     friend   ostream& operator<<(ostream& os,
  272.             CL<ITEM>& b);
  273.     friend   istream& operator>>(istream& is,
  274.             CL<ITEM>& b);
  275.     cl::     vforEach;
  276.  
  277.  
  278. public:
  279.  
  280. /*  Constructors and destructor  */
  281.  
  282.     CL (unsigned flags = CL_BIND_ONLY,
  283.         unsigned maxNodes = CL_MAXNODES,
  284.         unsigned limit = CL_LIMIT,
  285.         unsigned delta = CL_DELTA) :
  286.         cl(flags,maxNodes,limit,delta)
  287.         {}
  288.     CL (ITEM * argv[],
  289.         unsigned argc = 0U,
  290.         unsigned flags = CL_BIND_ONLY)
  291.         : cl((void **)argv,argc,flags)
  292.         {}
  293.     CL (CL<ITEM>& b)
  294.         : cl(defaultConstruct)
  295.         { assign(b); }
  296.     CL<ITEM>& operator=(CL<ITEM>& b)
  297.         { assign(b); return *this; }
  298.     int     operator==(const CL<ITEM>& b) const
  299.         { return cl::operator==(b); }
  300.     int     operator> (const CL<ITEM>& b) const
  301.         { return cl::operator>(b); }
  302.     CL (const char * filename)
  303.         : cl(defaultConstruct)
  304.         { (void) cl::load(filename); }
  305.     int     load(const char * filename)
  306.         { return cl::load(filename); }
  307.     int     save(const char * filename)
  308.         { return cl::save(filename); }
  309.     ITEM ** vector(ITEM ** argv = (ITEM **)0,
  310.         unsigned argc = 0U) const
  311.         { return (ITEM **)cl::
  312.         vector((void **)argv,argc); }
  313.     virtual ~CL() { destruct(); }
  314.  
  315.  
  316. /*  Housekeeping Primitives  */
  317.  
  318.     cl::    Limit;
  319.     cl::    setLimit;
  320.     cl::    pack;
  321.     cl::    Delta;
  322.     cl::    setDelta;
  323.     cl::    Nodes;
  324.     cl::    MaxNodes;
  325.     cl::    setMaxNodes;
  326.     cl::    vacancy;
  327.     cl::    vacancyNonElastic;
  328.     cl::    Flags;
  329.     cl::    setFlags;
  330.     cl::    resetFlags;
  331.     CL<ITEM>&  operator<<(CL<ITEM>&
  332.             (*manipulator)(CL<ITEM>&))
  333.             { return (manipulator?
  334.             (*manipulator)
  335.             (*this)    : *this); }
  336.  
  337.  
  338. /*  Elastic Array Primitives  */
  339.  
  340.     ITEM *   atIns(unsigned n, ITEM * D)
  341.             { return (ITEM *)cl::
  342.             atIns(n,(void *)D); }
  343.     ITEM *   atInsNew(unsigned n, const ITEM * D)
  344.             { return (ITEM *)cl::
  345.             atInsNew(n,(const void *)D); }
  346.     ITEM *   atRmv(unsigned n)
  347.             { return (ITEM *)cl::
  348.             atRmv(n); }
  349.     cl::     allRmv;
  350.     cl::     atDel;
  351.     ITEM *   atDelAsg(unsigned n, ITEM * D)
  352.             { return (ITEM *)cl::
  353.             atDelAsg(n,(void *)D); }
  354.     cl::     allDel;
  355.     cl::     allClr;
  356.     ITEM *   atPut(unsigned n, ITEM * D)
  357.             { return (ITEM *)cl::
  358.             atPut(n,(void *)D); }
  359.     ITEM *   atPutNew(unsigned n, const ITEM * D)
  360.             { return (ITEM *)cl::
  361.             atPutNew(n,(const void *)D); }
  362.     ITEM *   atPutAsg(unsigned n, const ITEM * D)
  363.             { return (ITEM *)cl::
  364.             atPutAsg(n,(const void *)D); }
  365.     ITEM *   atGet(unsigned n) const
  366.             { return (ITEM *)cl::
  367.             atGet(n); }
  368.     ITEM *   operator[](unsigned n) const
  369.             { return atGet(n); }
  370.     ITEM *   atGetAsg(unsigned n, ITEM * D)
  371.             { return (ITEM *)cl::
  372.             atGetAsg(n,(void *) D); }
  373.     ITEM *   atXchg(unsigned n, ITEM * D)
  374.             { return (ITEM *)cl::
  375.             atXchg(n,(void *) D); }
  376.     unsigned index(const ITEM * D) const
  377.             { return cl::
  378.             index((const void *)D); }
  379.     void     forEach(CLapplY(B,ITEM), ...)
  380.             { va_list args;
  381.             va_start(args,B);
  382.             vforEach((voidApplY)B,args);
  383.             va_end(args); }
  384.  
  385.  
  386.  
  387. /*  Stack - Deque - Queue Primitives  */
  388.  
  389.     ITEM *   push(ITEM * D)
  390.             { return (ITEM *)cl::
  391.             push((void *) D); }
  392.     ITEM *   pushNew(const ITEM * D)
  393.             { return (ITEM *)cl::
  394.             pushNew((const void *)D); }
  395.     ITEM *   pop()
  396.             { return (ITEM *)cl::
  397.             pop(); }
  398.     CL<ITEM>&  operator>>(ITEM *& D)
  399.             { D = atRmv(0U);
  400.             return *this; }
  401.     cl::     popDel;
  402.     ITEM *   popDelAsg(ITEM * D)
  403.             { return (ITEM *)cl::
  404.             popDelAsg((void *)D); }
  405.     ITEM *   top() const
  406.             { return (ITEM *)cl::
  407.                 top(); }
  408.     ITEM *   topAsg(ITEM * D)
  409.             { return (ITEM *)cl::
  410.             topAsg((void *)D); }
  411.     ITEM *   insQ(ITEM * D)
  412.             { return (ITEM *)cl::
  413.             insQ((void *)D); }
  414.     CL<ITEM>&  operator<<(ITEM * D)
  415.             { atIns(Nodes(),D);
  416.                    return *this; }
  417.     ITEM *   insQNew(const ITEM * D)
  418.             { return (ITEM *)cl::
  419.             insQNew((const void *)D); }
  420.     ITEM *   unQ()
  421.             { return (ITEM *)cl::
  422.             unQ(); }
  423.     cl::     unQDel;
  424.     ITEM *   unQDelAsg(ITEM * D)
  425.             { return (ITEM *)cl::
  426.             unQDelAsg((void *)D); }
  427.     ITEM *   rear() const
  428.             { return (ITEM *)cl::
  429.                 rear(); }
  430.     ITEM *   rearAsg(ITEM * D)
  431.             { return (ITEM *)cl::
  432.             rearAsg((void *)D); }
  433.  
  434.  
  435. /*  List (single and double linked) Primitives  */
  436.  
  437.     cl::     CurNode;
  438.     cl::     setCurNode;
  439.     ITEM *   ins(ITEM * D)
  440.             { return (ITEM *)cl::
  441.             ins((void *)D); }
  442.     ITEM *   insNew(const ITEM * D)
  443.             { return (ITEM *)cl::
  444.             insNew((const void *)D); }
  445.     ITEM *   rmv()
  446.             { return (ITEM *)cl::
  447.             rmv(); }
  448.     cl::     del;
  449.     ITEM *   delAsg(ITEM * D)
  450.             { return (ITEM *)cl::
  451.             delAsg((void *)D); }
  452.     ITEM *   put(ITEM * D)
  453.             { return (ITEM *)cl::
  454.             put((void *)D); }
  455.     ITEM *   putNew(const ITEM * D)
  456.             { return (ITEM *)cl::
  457.             putNew((const void *)D); }
  458.     ITEM *   putAsg(const ITEM * D)
  459.             { return (ITEM *)cl::
  460.             putAsg((const void *)D); }
  461.     ITEM *   get() const
  462.             { return (ITEM *)cl::
  463.             get(); }
  464.     operator ITEM *() const { return get(); }
  465.     ITEM *   getAsg(ITEM * D)
  466.             { return (ITEM *)cl::
  467.             getAsg((void *)D); }
  468.     ITEM *   next()
  469.             { return (ITEM *)cl::
  470.             next(); }
  471.     ITEM *   operator++()
  472.             { return next(); }
  473.     ITEM *   nextAsg(ITEM * D)
  474.             { return (ITEM *)cl::
  475.             nextAsg((void *)D); }
  476.     ITEM *   prev()
  477.             { return (ITEM *)cl::
  478.             prev(); }
  479.     ITEM *   operator--()
  480.             { return prev(); }
  481.     ITEM *   prevAsg(ITEM * D)
  482.             { return (ITEM *)cl::
  483.             prevAsg((void *)D); }
  484.  
  485.  
  486. /* Priority Q, Set, Bag, Dictionary, Sort Primitives */
  487.  
  488.     cl::     Sorted;
  489.     cl::     unSort;
  490.     void     setCmP(CLcmP(cmP,ITEM)
  491.             = CLcmP0(ITEM))
  492.             { cl::setCmP
  493.             ((voidCmP)cmP); }
  494.     CLcmP(CmPfnc,ITEM) { return CLcmPcast
  495.             (cl::CmP(),ITEM); }
  496.     int      sort(CLcmP(cmP,ITEM)
  497.             = CLcmP0(ITEM))
  498.             { return cl::sort
  499.             ((voidCmP)cmP); }
  500.     ITEM *   insSort(ITEM * D)
  501.             { return (ITEM *)cl::
  502.             insSort((void *)D); }
  503.     ITEM *   insSortNew(const ITEM * D)
  504.             { return (ITEM *)cl::
  505.             insSortNew((const void *)D); }
  506.     ITEM *   insUnique(ITEM * D)
  507.             { return (ITEM *)cl::
  508.             insUnique((void *)D); }
  509.     ITEM *   insUniqueNew(const ITEM * D)
  510.             { return (ITEM *)cl::
  511.             insUniqueNew((const void *)D);}
  512.     ITEM *   findFirst(const ITEM * K)
  513.             { return (ITEM *)cl::
  514.             findFirst((const void *)K); }
  515.     ITEM *   operator[](const ITEM * K)
  516.             { return findFirst(K); }
  517.     ITEM *   findNext(const ITEM * K)
  518.             { return (ITEM *)cl::
  519.             findNext((const void *)K); }
  520.     ITEM *   findLast (const ITEM * K)
  521.             { return (ITEM *)cl::
  522.             findLast((const void *)K); }
  523.     ITEM *   findPrev(const ITEM * K)
  524.             { return (ITEM *)cl::
  525.             findPrev((const void *)K); }
  526.     unsigned findAll(const ITEM * K)
  527.             { return cl::
  528.             findAll((const void *)K); }
  529.  
  530.  
  531. };    /*  class CL  */
  532.  
  533.  
  534. template <class ITEM>
  535. inline ostream& operator<<(ostream& os,
  536.         CL<ITEM>& b)
  537.     { (void) b.put(os); return os; }
  538.  
  539. template <class ITEM>
  540. inline istream& operator>>(istream& is,
  541.         CL<ITEM>& b)
  542.     { (void) b.get(is); return is; }
  543.  
  544.  
  545. #endif  /*  cl_hpt  */
  546.